package com.crowntit.service.weixin;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.apache.commons.lang3.StringUtils;

import java.io.Writer;

public class XmlUtil {
    public static <T> T xmlToBean(String xml, Class clazz){
        XStream stream = new XStream(new DomDriver());
        XStream.setupDefaultSecurity(stream);

        stream.allowTypes(new Class[]{clazz});
        stream.processAnnotations(new Class[]{clazz});
        stream.setMode(XStream.NO_REFERENCES);
        stream.alias("xml", clazz);  //"xml"是微信返回的数据体中最外层节点
        return (T) stream.fromXML(xml);
    }

    public static String beanToXml(Object object){
        XStream stream = getWeixinXStream();
        stream.alias("xml", object.getClass());
        stream.processAnnotations(object.getClass());
        String xml = stream.toXML(object);

        if (!StringUtils.isEmpty(xml)){
            return xml;
        } else {
            return null;
        }
    }

    /**
     * 微信传输的xml数据，每个节点（数据）前都有CDATA标识，返回的时候同步加上
     * @return
     */
    public static XStream getWeixinXStream(){
        return new XStream(new XppDriver() {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out){
                    boolean cdata = true;

                    @Override
                    public void startNode(String name, Class clazz) {
                        super.startNode(name, clazz);
                    }

                    @Override
                    protected void writeText(QuickWriter writer, String text) {
                        if (cdata && !StringUtils.isNumeric(text)){
                            writer.write("<![CDATA[");
                            writer.write(text);
                            writer.write("]]>");
                        } else {
                            writer.write(text);
                        }
                    }
                };
            }
        });
    }
}
